# _*_coding:utf-8 _*_
# @Time    :2019/10/31 20:23
# @Author  :Dapan
# @Email   :248312738@qq.com

# 图片验证码
import random

from ihome import redis_store
from ihome.libs.yuntongxun.sms import CCP
from ihome.models import User
from . import api
from flask import current_app,jsonify,make_response,request
from ihome.utils.captcha.captcha import captcha
from ihome.utils.response_code import RET


@api.route('/image_codes/<image_code_id>')
def get_image_code(image_code_id):
    """
    获取图片验证码
    :return: 图片验证码
    """
    # 1、生成图片验证码
    # 名字, 验证码真实值，图片的二进制内容
    name, text, image_code_data = captcha.generate_captcha()
    # 2、将验证码的真实值与名字保存到redis中,并设置有效期
    # redis数据类型 哈希 image_codes:{"":"", "":"", "":"" }  设置有效期只能全部有效失效 不合适
    try:
        redis_store.setex("image_codes:%s"%image_code_id, time=current_app.config.get('IMAGE_CODES_REDIS_EXPIRES'), value=text)
    except Exception as e:
        current_app.logger.error(e)
        # 如果存入redis失败 图片也就没必要返回给前端了
        return jsonify(errno=RET.DATAERR, errmag='保存图片验证码信息失败')

    # 3、将图片二进制数据返回，并设置数据类型
    resp = make_response(image_code_data)
    resp.headers['Content-Type'] = "image/jpg"
    return resp


@api.route('/sms_codes/<re(r"1[34578]\d{9}"):mobile>')
def send_sms_codes(mobile):
    """发送短信验证码"""
    # url中提取参数
    image_code = request.args.get('image_code')
    image_code_id = request.args.get('image_code_id')

    # 判断参数是否完整
    if not all([image_code,image_code_id]):
        # 不完整 返回异常
        current_app.logger.error("发送短信验证码，参数不完整")
        return jsonify(errno=RET.PARAMERR, errmsg="参数不完整")

    # 获取真实图片验证码的值
    try:
        real_image_code = redis_store.get("image_codes:%s"%image_code_id).decode()
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR, errmsg="图片验证码验证失败，请刷新后重试")

    # 删除redis中的图片验证码，防止用户使用同一个图片验证码多次
    try:
        redis_store.delete('image_codes:%s'%image_code_id)
    except Exception as e:
        current_app.logger.error(e)

    if real_image_code is None:
        # 此时图片验证码过期
        return jsonify(errno=RET.NODATA, errmsg='图片验证码过期，请刷新后重试')

    # 判断图片验证码是否正确
    if real_image_code.lower() != image_code.lower():
        # 验证不通过
        return jsonify(errno=RET.DATAERR, errmsg="图片验证码验证失败，请刷新后重试")

    # 判断该手机号是否在60秒内已经发送过手机验证码
    try:
        is_send_sms_code = redis_store.get("is_send_sms_codes:%s" % mobile)
    except Exception as e:
        current_app.logger.error(e)
    else:
        if is_send_sms_code is not None:
            return jsonify(errno=RET.REQERR, errmsg="请求过于频繁，请在60秒后重试")

    # 判断手机号是否已注册
    try:
        user = User.query.filter_by(mobile=mobile).first()
    except Exception as e:
        current_app.logger.error(e)
    else:
        if user is not None:
            # 表示数据库中查到了该手机 若注册，返回提示信息
            return jsonify(errno=RET.DATAEXIST, errmsg="该手机号已经注册")


    # 生成短信验证码
    sms_code = "%06d"%random.randint(0,999999)
    # 将真的短信验证码保存到redis中
    try:
        redis_store.setex("sms_codes:%s"%mobile, time=current_app.config.get('SMS_CODES_REDIS_EXPIRES'), value=sms_code)
        # 保存60s内是否发送过短信的状态
        redis_store.setex("is_send_sms_codes:%s" % mobile, time=current_app.config.get('SEND_SMS_CODES_INTERVAL'),
                          value=1)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR, errmsg='发送短信验证码或 发送过短信的状态异常')

    # 发送手机验证码
    try:
        ccp = CCP()
        result = ccp.sendTemplateSMS(mobile, [sms_code, int(current_app.config.get('SMS_CODES_REDIS_EXPIRES')/60)], 1)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.THIRDERR, errmsg='发送短信验证码失败,第三方异常')

    # 判断是否发送成功
    if result == 0:
        return jsonify(errno=RET.OK, errmsg='发送短信验证码成功')
    else:
        return jsonify(errno=RET.THIRDERR, errmsg='发送短信验证码失败')
